package top.z.orm.core.osql;

import java.util.List;

/**
 * 数据库操作接口,包括查,改,增,删 Suid (select,update,insert,delete),该接口比Suid接口提供更多的参数选择
 */
public interface SuidRich extends Suid {

    /**
     * 根据实体对象entity查询数据,且可以分页
     *
     * @param entity 实体类对象,且不能为空,entity中非null且非空字符串作为过虑条件,操作符是等号.eg:field=value
     * @param size   结果集大小 大于等于1
     * @return 可包含多个实体(多条记录)的list
     */
    <T> List<T> select(T entity, int size);

    /**
     * 根据实体对象entity查询数据,且可以分页
     *
     * @param entity 实体类对象,且不能为空,entity中非null且非空字符串作为过虑条件,操作符是等号.eg:field=value
     * @param start  开始下标(从0或1开始,eg:MySQL是0,Oracle是1)
     * @param size   结果集大小 大于等于1. fetch result size (>0).
     * @return 可包含多个实体(多条记录)的list
     */
    <T> List<T> select(T entity, int start, int size);

    /**
     * 查询实体时,只查询部分一部分字段
     *
     * @param entity 实体类对象,且不能为空
     * @param fields 需要查询的字段,多个用逗号隔开
     * @return 可包含多个实体(多条记录)的list
     */
    <T> List<T> select(T entity, String fields);

    /**
     * 查询实体时,只查询部分一部分字段,且可以分页
     *
     * @param entity 实体类对象,且不能为空
     * @param fields 需要查询的字段,多个用逗号隔开
     * @param start  开始下标(从0或1开始,eg:MySQL是0,Oracle是1)
     * @param size   结果集大小 大于等于1
     * @return 可包含多个实体(多条记录)的list
     */
    <T> List<T> select(T entity, String fields, int start, int size);

    /**
     * 查询实体,每个字段都是以字符串类型返回
     *
     * @param entity 实体类对象,且不能为空
     * @return 可包含多个String数组结构的多条记录的list
     */
    <T> List<String[]> selectString(T entity);

    /**
     * 查询部分字段,每个字段都是以字符串类型返回
     *
     * @param entity 实体类对象,且不能为空
     * @param fields 需要查询的字段,多个用逗号隔开
     * @return 可包含多个String数组结构的多条记录的list
     */
    <T> List<String[]> selectString(T entity, String fields);

    /**
     * 不以具体实体结构返回数据,而是用字符数组的List
     *
     * @param entity    实体类对象,且不能为空
     * @param condition condition.若condition没有设置IncludeType,默认过滤NULL和空字符串(但condition中op,between,notBetween方法设置的字段,不受includeType的值影响.)
     * @return 可包含多个String数组结构的多条记录的list
     */
    <T> List<String[]> selectString(T entity, Condition condition);

    /**
     * 根据实体对象entity查询数据,并返回Json格式结果
     *
     * @param entity 与表对应的实体对象,且不能为空
     *               entity中非null与非空字符串作为过虑条件,操作符是等号.eg:field=value
     * @return 可包含多个实体(多条记录)的list转换成的json格式的字符串
     */
    <T> String selectJson(T entity);

    /**
     * 查询一个实体
     *
     * @param entity 实体类对象
     * @return 只返回一个实体, 数量不为1时返回null
     */
    <T> T selectOne(T entity);

    /**
     * 使用函数查询一个统计结果
     *
     * @param entity       传入的实体对象,且不能为空
     * @param functionType MAX,MIN,SUM,AVG,COUNT
     * @param fieldForFun  需要使用函数的字段
     * @return 一个函数查询的结果
     */
    <T> String selectWithFun(T entity, FunctionType functionType, String fieldForFun);

    /**
     * 使用函数查询一个统计结果,通过Condition可添加复杂过滤条件.只查询一个统计结果
     *
     * @param entity       传入的实体对象,且不能为空
     * @param functionType MAX,MIN,SUM,AVG,COUNT
     * @param fieldForFun  需要使用函数的字段
     * @param condition    condition.若condition没有设置IncludeType,默认过滤NULL和空字符串(但condition中op,between,notBetween方法设置的字段,不受includeType的值影响.)
     *                     <br>condition的selectFun方法将被忽略
     * @return 一个函数查询的结果
     */
    <T> String selectWithFun(T entity, FunctionType functionType, String fieldForFun, Condition condition);

    /**
     * 统计记录总数
     *
     * @param entity 实体类对象,且不能为空
     * @return 统计记录行数
     */
    <T> Integer count(T entity);

    /**
     * 统计记录总数
     *
     * @param entity    实体类对象,且不能为空
     * @param condition condition用于设置过滤条件
     * @return 统计记录行数
     */
    <T> Integer count(T entity, Condition condition);

    /**
     * 查询应用排序的结果,排序的字段默认按升序排列
     *
     * @param entity 传入的实体对象,且不能为空
     * @param fields 排序字段列表,多个用逗号隔开
     * @return 可包含多个有排序的实体(多条记录)的list
     */
    <T> List<T> selectOrderBy(T entity, String fields);

    /**
     * 查询应用排序的结果
     *
     * @param entity      传入的实体对象,且不能为空
     * @param orderFields 排序字段列表,多个用逗号隔开
     * @param orderTypes  排序类型列表
     * @return 可包含多个有排序的实体(多条记录)的list
     */
    <T> List<T> selectOrderBy(T entity, String orderFields, OrderType[] orderTypes);

    /**
     * 更新记录,且可以指定需要更新的字段
     *
     * @param entity       实体类对象,不能为空
     * @param updateFields 需要更新的字段列表,多个字段用逗号隔开(列表中有的字段都会更新),该属性不允许为空
     *                     除了updateFields中声明要更新的字段,其它非空,非null的字段作为过滤条件,转成SQL的where表达式
     * @return 成功更新的记录数
     */
    <T> Integer update(T entity, String updateFields);

    /**
     * 根据实体对象entity更新数据,可以指定需要更新的字段
     *
     * @param entity       与表对应的实体对象,且不能为空
     *                     id为null不作为过滤条件
     * @param updateFields 需要更新的字段列表,多个字段用逗号隔开(列表中有的字段都会更新),该属性不允许为空,且不受includeType参数的影响,默认每个字段会被转化成SQL update的set表达式
     * @param includeType  空字符串与null是否包含设置(是否作为过滤条件)
     * @return 成功更新的记录数
     */
    <T> Integer update(T entity, String updateFields, IncludeType includeType);

    /**
     * 批量插入数据
     *
     * @param entity 与表对应的实体对象数组,且不能为空
     * @return 成功插入的记录行数
     */
    <T> Integer insert(T[] entity);

    /**
     * 批量插入数据
     *
     * @param entity    与表对应的实体对象,且不能为空
     * @param batchSize 批操作数量大小
     * @return 成功插入的记录行数
     */
    <T> Integer insert(T[] entity, int batchSize);

    /**
     * 批量插入数据,且可以声明不用插入的字段列表
     *
     * @param entity        与表对应的实体对象数组,且不能为空
     * @param excludeFields 声明不用插入的字段列表
     * @return 成功插入的记录行数
     */
    <T> Integer insert(T[] entity, String excludeFields);

    /**
     * 批量插入数据,且可以指定不用插入的字段列表
     *
     * @param entity        与表对应的实体对象数组,且不能为空
     * @param batchSize     批操作数量大小
     * @param excludeFields 声明不用插入的字段列表
     * @return 成功插入的记录行数
     */
    <T> Integer insert(T[] entity, int batchSize, String excludeFields);

    /**
     * 批量插入数据
     *
     * @param entityList 与表对应的实体对象链表,且不能为空
     * @return 成功插入的记录行数
     */
    <T> Integer insert(List<T> entityList);

    /**
     * 批量插入数据.Insert records by batch type.
     *
     * @param entityList 与表对应的实体对象链表,且不能为空
     * @param batchSize  批操作数量大小
     * @return 成功插入的记录行数
     */
    <T> Integer insert(List<T> entityList, int batchSize);

    /**
     * 批量插入数据,且可以声明不用插入的字段列表
     *
     * @param entityList    与表对应的实体对象链表,且不能为空
     * @param excludeFields 声明不用插入的字段列表
     * @return 成功插入的记录行数
     */
    <T> Integer insert(List<T> entityList, String excludeFields);

    /**
     * 批量插入数据,且可以指定不用插入的字段列表
     *
     * @param entityList    与表对应的实体对象链表,且不能为空
     * @param batchSize     批操作数量大小
     * @param excludeFields 声明不用插入的字段列表
     * @return 成功插入的记录行数
     */
    <T> Integer insert(List<T> entityList, int batchSize, String excludeFields);

    /**
     * 根据实体对象entity查询数据
     *
     * @param entity      实体类对象,且不能为空,entity中非null且非空字符串作为过虑条件,操作符是等号.eg:field=value
     * @param includeType 空字符串与null是否包含设置
     * @return 可包含多个实体(多条记录)的list
     */
    <T> List<T> select(T entity, IncludeType includeType);

    /**
     * 根据实体对象entity中id更新该实体对象的数据
     *
     * @param entity      与表对应的实体对象,且不能为空;entity中id字段不能为空,作为过虑条件,id为null将引发ObjSQLException
     * @param includeType 空字符串与null是否包含设置
     * @return 成功更新的记录数
     */
    <T> Integer update(T entity, IncludeType includeType);

    /**
     * 根据实体对象entity插入数据
     *
     * @param entity      与表对应的实体对象,且不能为空
     * @param includeType 空字符串与null是否包含设置
     * @return 成功插入的记录行数
     */
    <T> Integer insert(T entity, IncludeType includeType);

    /**
     * 根据实体对象entity删除数据
     *
     * @param entity      与表对应的实体对象,且不能为空,id为null不作为过滤条件
     * @param includeType 空字符串与null是否包含设置
     * @return 成功删除的记录行数
     */
    <T> Integer delete(T entity, IncludeType includeType);

    /**
     * 根据实体对象entity查询并返回Json格式的数据
     *
     * @param entity      与表对应的实体对象,且不能为空
     *                    id为null不作为过滤条件
     * @param includeType 空字符串与null是否包含设置
     * @return 可包含多个实体(多条记录)的list转换成的json格式的字符串
     */
    <T> String selectJson(T entity, IncludeType includeType);

    /**
     * 根据id查询记录
     *
     * @param entity 实体类对象,且不能为空
     * @param id     实体id字段的值
     * @return 返回id对应的实体
     */
    <T> T selectById(T entity, Integer id);

    /**
     * 根据id查询记录
     *
     * @param entity 实体类对象,且不能为空
     * @param id     实体id字段的值
     * @return 返回id对应的实体
     */
    <T> T selectById(T entity, Long id);

    /**
     * 根据id查询记录
     *
     * @param entity 实体类对象,且不能为空
     * @param id     实体id字段的值
     * @return 返回id对应的实体
     */
    <T> T selectById(T entity, String id);

    /**
     * 根据id查询记录
     *
     * @param entity 实体类对象,且不能为空
     * @param ids    实体id字段的值,多个用逗号隔开
     * @return 可包含多个实体(多条记录)的list
     */
    <T> List<T> selectByIds(T entity, String ids);

    /**
     * 根据id删除记录
     *
     * @param clazz 实体类类型,且不能为空
     * @param id    实体id字段的值
     * @return 成功删除的记录行数
     */
    Integer deleteById(Class<?> clazz, Integer id);

    /**
     * 根据id删除记录
     *
     * @param clazz 实体类类型,且不能为空
     * @param id    实体id字段的值
     * @return 成功删除的记录行数
     */
    Integer deleteById(Class<?> clazz, Long id);

    /**
     * 根据id删除记录
     *
     * @param clazz 实体类类型,且不能为空
     * @param ids   实体id字段的值,多个用逗号隔开
     * @return 成功删除的记录行数
     */
    Integer deleteById(Class<?> clazz, String ids);

    /**
     * 根据实体对象entity查询数据,并以Json格式返回
     *
     * @param entity    与表对应的实体对象,且不能为空,id为null不作为过滤条件
     * @param condition entity默认有值的字段会转成field=value的形式,其它形式可通过condition指定.condition使用过的字段,默认情况不会再处理.<br>
     *                  若condition没有设置IncludeType,默认过滤NULL和空字符串(但condition中op,between,notBetween方法设置的字段,不受includeType的值影响.)
     * @return 可包含多个实体(多条记录)的list转换成的json格式的字符串
     */
    <T> String selectJson(T entity, Condition condition);

    /**
     * 更新记录,且可以指定作为条件的字段
     *
     * @param entity      实体类对象,不能为空,没指定为whereFields的字段,作为set部分,默认只处理非空,非null的字段
     * @param whereFields 作为SQL中where条件的字段列表,多个字段用逗号隔开(列表中有的字段都会作为条件);指定作为条件的,都转换.id为null不作为过滤条件
     * @return 成功更新的记录数
     */
    <T> Integer updateBy(T entity, String whereFields);

    /**
     * 更新记录,且可以指定作为条件的字段和指定字段的过滤类型
     *
     * @param entity      与表对应的实体对象,且不能为空,没指定为whereFields的字段,作为set部分.
     * @param whereFields 作为SQL中where条件的字段列表,多个字段用逗号隔开(列表中有的字段都会作为条件);指定作为条件的,都转换.id为null不作为过滤条件
     * @param includeType 空字符串与null是否包含设置(是否作为过滤条件)
     * @return 成功更新的记录数
     */
    <T> Integer updateBy(T entity, String whereFields, IncludeType includeType);

    /**
     * 更新记录,且可以指定作为条件的字段
     *
     * @param entity      实体类对象,不能为空,没指定为whereFields的字段,作为set部分(默认只处理非空,非null的字段)
     * @param whereFields 作为SQL中where条件的字段列表,多个字段用逗号隔开(列表中有的字段都会作为条件);指定作为条件的,都转换.id为null不作为过滤条件
     *                    需要注意的是,用condition的op方法设置的条件,即使whereFields没有声明,也会转换.
     * @param condition   用来设置默认情况不能表达的条件.若condition没有设置IncludeType,默认过滤NULL和空字符串(但condition中op,between,notBetween方法设置的字段,不受includeType的值影响.)
     * @return 成功更新的记录数
     */
    <T> Integer updateBy(T entity, String whereFields, Condition condition);

    /**
     * 此方法,相当于SuidRich接口的 updateBy(entity,"id",condition);
     * 更新记录,且可以指定作为条件的字段
     *
     * @param entity    实体类对象,不能为空
     *                  entity中除了id字段,作为set部分(默认只处理非空,非null的字段)
     * @param condition 用来设置默认情况不能表达的条件.
     *                  若condition没有设置IncludeType,默认过滤NULL和空字符串(但condition中op,between,notBetween方法设置的字段,不受includeType的值影响.)
     *                  <br>需要注意的是,condition用op设置的条件,也有可能转换为where部分的过滤条件.
     * @return 成功更新的记录数
     */
    <T> Integer updateById(T entity, Condition condition);

    /**
     * 更新记录,且可以指定需要更新的字段,高级条件可通过Condition参数设置
     *
     * @param entity       实体类对象,不能为空.entity默认有值的字段会转成field=value的形式,其它形式可通过condition指定.condition中op,between等方法设置的转换到where中的字段,默认情况不会再处理.<br>
     * @param updateFields 需要更新的字段列表,多个字段用逗号隔开(列表中有的字段都会更新),该属性不允许为空,
     *                     <br>默认updateFields的每个字段会被转化成SQL update的set表达式;其它非空,非null的字段作为过滤条件,转成SQL的where表达式.
     * @param condition    若condition没有设置IncludeType,默认过滤NULL和空字符串(但condition中op,between,notBetween方法设置的字段,不受includeType的值影响.)
     * @return 成功更新的记录数
     */
    <T> Integer update(T entity, String updateFields, Condition condition);

    /**
     * 当SQL update的set表达式通过Condition定义时,可以不用再指定set使用的字段.
     *
     * @param entity    实体类对象,不能为空
     *                  entity默认有值的字段会转成field=value的形式,其它形式可通过condition指定.condition中op,between等方法设置的转换到where中的字段,默认情况不会再处理.<br>
     * @param condition 若condition没有设置IncludeType,默认过滤NULL和空字符串(但condition中op,between,notBetween方法设置的字段,不受includeType的值影响.)
     * @return 成功更新的记录数
     */
    <T> Integer update(T entity, Condition condition);
}